/********************************************************************************************************
 * @file	acl_stack.h
 *
 * @brief	This is the header file for BLE SDK
 *
 * @author	BLE GROUP
 * @date	2020.06
 *
 * @par     Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK")
 *          All rights reserved.
 *
 *          Redistribution and use in source and binary forms, with or without
 *          modification, are permitted provided that the following conditions are met:
 *
 *              1. Redistributions of source code must retain the above copyright
 *              notice, this list of conditions and the following disclaimer.
 *
 *              2. Unless for usage inside a TELINK integrated circuit, redistributions
 *              in binary form must reproduce the above copyright notice, this list of
 *              conditions and the following disclaimer in the documentation and/or other
 *              materials provided with the distribution.
 *
 *              3. Neither the name of TELINK, nor the names of its contributors may be
 *              used to endorse or promote products derived from this software without
 *              specific prior written permission.
 *
 *              4. This software, with or without modification, must only be used with a
 *              TELINK integrated circuit. All other usages are subject to written permission
 *              from TELINK and different commercial license may apply.
 *
 *              5. Licensee shall be solely responsible for any claim to the extent arising out of or
 *              relating to such deletion(s), modification(s) or alteration(s).
 *
 *          THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 *          ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 *          WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *          DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY
 *          DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 *          (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *          LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 *          ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *          (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 *          SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *******************************************************************************************************/
#ifndef ACL_STACK_H_
#define ACL_STACK_H_


#include "stack/ble/ble_common.h"
#include "stack/ble/ble_stack.h"
#include "stack/ble/ble_config.h"
#include "stack/ble/ble_format.h"

#include "stack/ble/controller/ll/ll_stack.h"
#include "stack/ble/controller/csa/csa_stack.h"
#include "stack/ble/controller/phy/phy_stack.h"

#include "algorithm/aes_ccm/aes_ccm.h"


/******************************* acl_conn start ******************************************************************/
#define			BLM_CONN_HANDLE									BIT(7)
#define			BLS_CONN_HANDLE									BIT(6)
#define 		BLT_ACL_CONN_MASTER_HANDLE						BLM_CONN_HANDLE
#define 		BLT_ACL_CONN_SLAVE_HANDLE						BLS_CONN_HANDLE
#define			BLT_ACL_CONN_HANDLE								(BLT_ACL_CONN_MASTER_HANDLE | BLT_ACL_CONN_SLAVE_HANDLE)

#define			BLT_SYNC_HANDLE									BIT(3)


#define			CONN_IDX_MASK									15



#define			MAX_OCTETS_DATA_LEN_27							27
#define			MAX_OCTETS_DATA_LEN_EXTENSION					251


/////////////////////////////////////////////////////////////////////////////
#define			HANDLE_STK_FLAG									BIT(15)
#define 		BLMS_STACK_USED_TX_FIFO_NUM      				2

/////////////////////////////////////////////////////////////////////////////



#define			LL_PACKET_OCTET_TIME(n)							((n) * 8 + 112)

#define 		DATA_LENGTH_REQ_PENDING							1
#define 		DATA_LENGTH_RSP_PENDING							2



#define			ENHANCED_CONN_FLAG_AUX_CONNECT					BIT(1)
#define			ENHANCED_CONN_FLAG_CSA2							BIT(2)

#define			ENHANCED_CONN_FLAG_ALL							(ENHANCED_CONN_FLAG_AUX_CONNECT | ENHANCED_CONN_FLAG_CSA2)

/**
 *  @brief  Definition for LLID of Data Physical Channel PDU header field
 */
#define 				LLID_RESERVED				0x00
#define 				LLID_DATA_CONTINUE			0x01
#define 				LLID_DATA_START				0x02
#define 				LLID_CONTROL				0x03


//////////////////////////////// LL ENC ///////////////////////////////////
#define			MS_LL_ENC_OFF									0
#define			MS_LL_ENC_REQ									1
#define			MS_LL_ENC_RSP_T									2
#define			MS_LL_ENC_START_REQ_T							3
#define			MS_LL_ENC_START_REQ								4
#define			MS_LL_ENC_START_RSP_T							5
#define			MS_LL_ENC_PAUSE_REQ								6
#define			MS_LL_ENC_PAUSE_RSP_T							7
#define			MS_LL_ENC_PAUSE_RSP								8
#define			MS_LL_REJECT_IND_T								9
#define         MS_LL_ENC_SMP_INFO_S                			10
#define         MS_LL_ENC_SMP_INFO_E                			11

#define			MS_CONN_ENC_CHANGE								BIT(7)
#define			MS_CONN_ENC_REFRESH								BIT(6)
#define			MS_CONN_ENC_REFRESH_T							BIT(5)





#define		 	CONN_STATUS_DISCONNECT							0   //disconnect must be "0"
#define			CONN_STATUS_COMPLETE							1
#define			CONN_STATUS_ESTABLISH							2


#if BQB_TEST_EN
#define 		BLMS_CONN_CREATE_RX_MAX_TRY_NUM					6
#else
#define 		BLMS_CONN_CREATE_RX_MAX_TRY_NUM					4
#endif
#define 		BLMS_CONN_UPDATE_BRX_MAX_TRY_NUM				6




#define			CONN_UPDATE_MAP 								BIT(0)


#define			CONN_UPDATE_CMD									BIT(1)
#define			CONN_UPDATE_PENDING								BIT(2)
#define			CONN_UPDATE_NEARBY								BIT(3)
#define			CONN_UPDATE_SYNC								BIT(4)

#define         CONN_PHY_UPDATE_IND_CMD                         BIT(5)


_attribute_aligned_(4)
typedef struct {
	u16		connEffectiveMaxRxOctets;
	u16		connEffectiveMaxTxOctets;
	u16 	connMaxRxOctets;
	u16 	connMaxTxOctets;
	u16		connRemoteMaxRxOctets;
	u16 	connRemoteMaxTxOctets;
	u16		supportedMaxRxOctets;
	u16		supportedMaxTxOctets;

	u8	 	connInitialMaxTxOctets;  //u8 is enough
	u8		connMaxTxRxOctets_req;
	u8		connRxDiff100;  //not used now
	u8		connTxDiff100;  //not used now
}ll_data_extension_t;


typedef	struct {
	u16		size;
	u8		size_div_16;
	u8		num;

	u8		mask;
	u8		wptr;
	u8		rptr;
	u8		rsvd;

	u8*		p_base;
}acl_rx_fifo_t;
#if (MCU_CORE_TYPE == MCU_CORE_9518)
typedef	struct {
	u16		size;
	u16		conn_full_size;
	u8		depth;
	u8		real_num;
	u8		logic_num;
	u8		mask;

	u8*		p_base;
}acl_tx_fifo_t;
#else  ///kite vulture
typedef	struct {
	u16		size;
	u8		num;
	u8		mask;

	u8*		p_base;
}acl_tx_fifo_t;
#endif

typedef union {
	struct{
		u8		update_cmd;
		u8		update_param;
		u8		update_map;
		u8      update_phy;
	};
	u32 update_pack;
}conn_updt_t;

typedef union {
	struct{
		u8 		peer_terminate;
		u8 		local_terminate;
		u8		terminate_reason;
		u8		rsvd;
	};
	u32 termin_pack;
}conn_trmt_t;


typedef union {
	struct{
		u8		connect_evt;		//Event triggered by IRQ
		u8		disconn_evt;		//Event triggered by IRQ
		u8		conn_update_evt;	//Event triggered by IRQ
		u8		phy_update_evt;		//Event triggered by IRQ
	};
	u32 irqevt1_pack;
}irq_evt_1_t;




_attribute_aligned_(4)
typedef struct {
	conn_updt_t		conn_update_union;
	irq_evt_1_t		irq_event1_union;
	conn_trmt_t		conn_termin_union;

	u8		tx_wptr;
	u8		tx_rptr;
	u8		tx_num;
	u8		conn_fifo_flag;

	u8		max_fifo_num;
	u8		save_flg;
	u8		local_sn;
	u8		local_nesn;

	u8      conn_dma_tx_rptr;
	u8		peer_last_rfLen;
	u8		peer_last_sn;
	u8		role;

	u8		connState;			 // 0/Conn_Complete/Conn_Establish
	u8		chn_idx;
	u8		conn_chn;
	u8		conn_sca;


	u8		acl_conn_Index;
	s8		connUpt_inst_jump;
	u8		conn_updateEvt_pending; //hold this event until new conne_param_used
	u8      blt_tx_pkt_hold;


	u8		conn_receive_packet;       //optimize: different CONN share same variable
	u8		conn_receive_new_packet;   //optimize: different CONN share same variable
	u8  	connTermTxFifoWptr;
	u8		bSlot_shift_margin;

	u8		conn_chn_hop;
	u8		adv_handle;
	u8		num_completeTerminateEvt;
	u8		u8_rsvd[1];

	u8      conn_winsize_next;		//u8 is enough
	u8		conn_peerIdAddr[6];  //host event use addr
	u8	    conn_peerIdAddrType; //host event use addr type: 0,1,2,3




	u8      ll_enc_busy;
	u8      encryption_evt;		//Event triggered by MainLoop
	u8		encryption_tmp_st;
	u8 		ll_ver_exg_flg;

	u8		sync_timing;  		//slave used only
	u8		sync_num;			//slave used only
	u8  	sentLlOpcode;
	u8 		remoteFeatureReq;	//Only used by slave role


	u16		conn_interval;		    //u8: max interval 320mS, not enough for big interval such as 4S;  u16: max 81.9S
	u16		conn_interval_next;		//u8: max interval 320mS, not enough for big interval such as 4S;  u16: max 81.9S
	u16     conn_offset_next;		//u8: max interval 320mS, not enough for big interval such as 4S;  u16: max 81.9S
	u16		u16_rsvd;

	u16		conn_inst_next;
	u16     conn_phy_inst_next;
	u16		conn_para_inst_next;
	u16		conn_map_inst_next;	    //update conn_param & update_map should separate, update map may delay to process due to BRX slot dropped

	u16		conn_latency;
	u16		conn_latency_next;
	u16		conn_timeout_next;     //Note: unit 10mS
	u16		connHandle;

	u16		conn_inst;
	u16		conn_inst_mark;
	u16		bSlot_oft_num_next;  //used for master update connection, new interval bSlot offset number
	u16		enc_ediv;       		//EDIV

	u16		pm_error_us;
	u16		inter_jump_num;


	u16		conn_successive_miss;
	u16		bSlot_interval;       //u8: max 160mS, u16: max 40.96S
	u16		txrx_duration_us;
	u16		sSlot_duration; 	 //u16: max 1.3S, big enough

	u32		bSlot_mark_conn;
	u32		conn_tick_mark;

	u32		conn_update_tick;
	u32		conn_update_pre_bSlotIndex;
	u32		conn_terminate_tick;
	u32 	conn_interval_tick;
	u32		conn_timeout;
	u32     conn_established_tick;  
	u32 	ll_rsp_timeout_tick;    // PROCEDURE RESPONSE TIMEOUT
	u32		conn_tick;
	u32 	ll_remoteFeature;
	u32		conn_inst_u32;
  	u32     conn_crc_revert; //revert crc24 init value

#if (BLUETOOTH_VER == BLUETOOTH_VER_5_2)
	u32 	ll_remoteFeature1; //for core5.2 featureSet
#endif

#if (BLS_PROC_MASTER_UPDATE_REQ_IN_IRQ_ENABLE)
	u32		conn_pkt_rcvd;
	u32		conn_pkt_rcvd_no;
	u8 		*conn_pkt_dec_pending;
#endif

	u8		peer_adr_type;
	u8		peer_adr[6];
	u8		u8_rsvd3;

	u8		peer_chnSel;
	u8		conn_chnsel;
	u16		u16_rsvd1;

	u8		enc_random[8]; //RANDOM
	u8 		enc_skdm[8];   //master SKDm
	u8 		enc_skds[8];   //slave  SKDs
	u32		enc_ivs;       //slave  IVs
	u32		enc_ivm;       //master IVm

	ble_crypt_para_t	crypt;   //40 Byte


	//Channel parameters
	ll_mgrChnParam_t chnParam;
  	u32		aclAccessAddr;		//AA shall be set to the Access Address of the ACL connection
  	u32		aclCrcInit;			//The ACL's CRC_Init value
  	u8		nxtRempChmTbl[40];  //can optimize to 37 later
  	u8		nxtNumUsedChn;
  	u8		nxtChmTbl[5];
  	u16		chnIdentifier;		//the ACL connection's Channel Identifier


#if (HCI_SEND_NUM_OF_CMP_AFT_ACK)
	u8		nocAckMsk;
	u8		nocAckNum;
	u8		nocAckWptr;
	u8		nocAckRptr;

	u8		nocAclTxWptr[32];
  	u8		numOfCmpCnt[32];
#endif


#if (LL_FEATURE_ENABLE_LE_2M_PHY | LL_FEATURE_ENABLE_LE_CODED_PHY)
  	ll_conn_phy_t		connPhyCtrl;
#endif


#if (LL_FEATURE_ENABLE_LE_DATA_LENGTH_EXTENSION)
	ll_data_extension_t ext_data;
#endif


#if(LL_FEATURE_ENABLE_CONNECTED_ISO)

	u8		cisAllocate_msk;
	u8		cisEstablish_msk;
	u8		cisFlowFlg;
	u8		cisFlow_idx;		//current CIS creating flow CIS index

	u8		cig_idx;			//for CIG master: CIG master index; for CIG slave: CIG slave index
	u8		cig_id; //TODO: According to BQB<<LL. TS>>: Only test one set of CIG on an ACL, we do not consider establishing multiple CIG groups on one ACL for the time being.
	u8		cis_u8_rsvd2;
	u8		cis_u8_rsvd3;

	u8		cis_reject_reason;		//only for slave, BIT(7):accept; others: reject reason
  	u8     	acl_masCigIndex_slvCigId;  /* for master: Which CIG_ID the ACL belongs to; for slave: peer cig_id*/
	u8 		cis_peer_terminate;
	u8 		cis_local_terminate;



  	u32		cis_req_accept_timeout;

#endif

  	u32    llCtrlFlag;


} st_ll_conn_t;



_attribute_aligned_(4)
typedef struct {
	u8		conn_rx_num;
	u8		updateCmd_pending;
	u8		u8_rsvd[2];

	u32 	tick_connectDevice;
} acl_conn_para_t;  //ACL connection parameters

extern	_attribute_aligned_(4)	acl_conn_para_t		aclConn_param;




typedef int (*blms_LTK_req_callback_t)(u16 handle, u8* rand, u16 ediv);
typedef bool (*ll_push_fifo_handler_t) (u16, u8 *);





extern _attribute_aligned_(4)	volatile st_ll_conn_t	AA_blms[];   // AA_ just for debug
#define blms	AA_blms
extern	st_ll_conn_t* 		blms_pconn;
extern	volatile int			blms_conn_sel;
extern  acl_rx_fifo_t			blt_rxfifo;
extern	acl_tx_fifo_t			blt_m_txfifo;
extern	acl_tx_fifo_t			blt_s_txfifo;
extern ll_push_fifo_handler_t	ll_push_tx_fifo_handler;

extern ll_task_callback_t		ll_acl_slave_mlp_task_cb;


enum{
	CONN_UPD_FLAG = 0x01,
	CHN_MAP_FLAG  = 0x02,
	PHY_UPD_FLAG  = 0x04,
};
/**
 * @brief      This function is used to check whether the current handle parameter is legal and in the connected state.
 * @param[in]  connHandle - ACL connection handle.
 * @return     status, 0x00:  succeed
 * 					   other: failed
 */
ble_sts_t 	blt_ll_isAclhdlInvalid (u16 connHandle);

int 		blt_acl_conn_interrupt_task (int flag);
int 		blt_acl_conn_mainloop_task (int flag, void *p);

int			blt_ll_set_interval_level (u8 task_offset, u16 interval);
void  		blt_ll_reset_acl_conn(void);
int 		blt_ll_procConnectionEvent(u16 connHandle,  st_ll_conn_t* pc);
int 		blms_connect_common(st_ll_conn_t *pc, rf_packet_connect_t * pInit, bool);

int 		blms_start_pre_process(int);
int 		blms_start_common_1  (st_ll_conn_t *pc);
int 		blms_start_common_2  (st_ll_conn_t *pc);

bool 		blms_post_pre_process(void);
int 		blms_post_common_1(st_ll_conn_t *pc);
int 		blms_post_common_2(void);


int  		irq_acl_conn_rx(void);
int  		irq_acl_conn_tx(void);

int 		blt_ll_acl_conn_sync_process(int sync_ok);

u8  		blt_ll_getRealTxFifoNumber (u16 connHandle);
u8  		blt_llms_get_tx_fifo_max_num (u16 connHandle);

void 		blt_llms_pushToHWfifo(void);
void 		blt_llms_saveTxfifoRptr(void);

bool		blt_ll_pushAclChClassUpdPkt(u16 connHandle, u8 *pChm);
bool 		blt_llms_pushTxfifo(u16 connHandle, u8 *p);
void 		blt_llms_push_fifo_hw(void);
void 		blt_llms_update_fifo_sw(void);
bool 		blt_llmsPushLlCtrlPkt(u16 connHandle, u8 opcode, u8*pkt);

bool		blt_llms_unknownRsp(u16 connHandle, u8 unknownType);
bool		blt_llms_rejectInd(u16 connHandle, u8 opCode, u8 errCode, u8 extRejectInd);
int			blt_llms_main_loop_data (u16 connHandle, u8 *raw_pkt);
void 		blt_ll_rspTimeoutLoopEvt(u16 connHandle);
void 		blt_llms_procConnCreateConnParamUpdate(void);

void 		blt_llms_registerLtkReqEvtCb(blms_LTK_req_callback_t evtCbFunc);


int  		blt_llms_isConnectionEncrypted(u16 connHandle);

int 		blt_llms_startEncryption(u16 connHandle ,u16 ediv, u8* random, u8* ltk);

u8 			blt_llms_getConnState(u16 connHandle);

int			blt_ll_acl_conn_mainloop(void);

ble_sts_t   blt_ll_enc_proc_disConnect (u16 connHandle, u8 reason);
ble_sts_t   blt_hci_ltkRequestReply(u16 connHandle,  u8*ltk);
ble_sts_t   blt_hci_ltkRequestNegativeReply(u16 connHandle);



ble_sts_t	blc_hci_receiveHostACLData(u16 connHandle, u8 PB_Flag, u8 BC_Flag, u8 *pData );
ble_sts_t 	blc_hci_setTxDataLength (u16 connHandle, u16 tx, u16 txtime);
ble_sts_t 	blt_hci_rx_aclfifo_to_rf_txfifo(void);


#if (LL_FEATURE_ENABLE_CONNECTED_ISOCHRONOUS_STREAM_MASTER)
	typedef	ble_sts_t (*ll_cis_ctrl_handler_t)(st_ll_conn_t*, u16, u8, u8*);
	void 	blt_ll_registerCisMasterCtrlPduHandler (ll_cis_ctrl_handler_t handler);
	void 	blt_ll_registerCisSlaveCtrlPduHandler (ll_cis_ctrl_handler_t handler);
#endif

static inline u8 blt_llms_get_connEffectiveMaxTxOctets_by_connIdx(u16 conn_idx)
{
	#if (LL_FEATURE_ENABLE_LE_DATA_LENGTH_EXTENSION)
		return blms[conn_idx].ext_data.connEffectiveMaxTxOctets;
	#else
		return 27;
	#endif
}

static inline u8 blt_llms_get_connEffectiveMaxRxOctets_by_connIdx(u16 conn_idx)
{
	#if (LL_FEATURE_ENABLE_LE_DATA_LENGTH_EXTENSION)
		return blms[conn_idx].ext_data.connEffectiveMaxRxOctets;
	#else
		return 27;
	#endif
}


/******************************* acl_conn end   ******************************************************************/







/******************************* acl_slave start ******************************************************************/
#define 		ACL_SLAVE_NON_MODULAR							1   //save some RamCode





#if BLS_PROC_MASTER_UPDATE_REQ_IN_IRQ_ENABLE
	#if (MCU_CORE_TYPE == MCU_CORE_9518)
		#define	AES_CCM_DEC_US										200		//timing for running "aes_ll_ccm_decryption"
	#else //kite/vulture
		#error "feed tested value"
	#endif
#endif

#define			SLAVE_SYNC_CONN_CREATE							BIT(0)
#define			SLAVE_SYNC_CONN_UPDATE							BIT(1)
#define			SLAVE_SYNC_CONN_UPT_FAIL						BIT(2)


//TODO: SiHui 3+1+3 -> change to 2+1+2 to save some time
#define			BRX_EARLY_SET_TICK	   						    2185  //312.5*7=2185.7  = 136.7uS
#define			BRX_EARLY_SET_SSLOT_NUM	   						7

#define			BRX_HALF_MARGIN_TICK	   						938  //312.5*3=937.5
#define			BRX_HALF_MARGIN_SSLOT_NUM		   				3

#define			BRX_LEFT_EARLY_TICK								(BRX_EARLY_SET_TICK + BRX_HALF_MARGIN_TICK)
#define			BRX_MARGIN_SSLOT_NUM							(BRX_EARLY_SET_SSLOT_NUM + BRX_HALF_MARGIN_SSLOT_NUM*2 + 1)

#define			ACL_SLAVE_FIFONUM								12

_attribute_aligned_(4)
typedef struct {
	u8		acl_slv_Index;
	s8		brx_pkt_miss;
	u8		brx_cal_synced;
	u8		brx_cal_long_sleep_synced;


	s8      ppm_cal_idx_cur;
	s8      ppm_cal_idx_last;
	s8 		ppm_idx;
	u8		u8_rsvd1[1];

	u16 	conn_tolerance_us;
	u16		tolerance_max_us;

	s32		conn_offset_tick;
	u32		tick_1st_rx;
	u32		tick_last_1st_rx;
  	u32		sleep_sys_ms;
  	u32		sleep_32k_rc;


//0x00
	u8		u8_rsvd2;
	u8		timing_update;
	u8		latency_wakeup_flg;
	u8		slave_sleep_flg;

	u16		evtCnt_mark_1strx;
	u16		latency_used;
	u16		latency_available;
	u16		u16_rsvd;

	s16		sSlot_offset;
	s16		sSlot_shift_tor;  //sSlot number shift for current tolerance

	u32		tick_mark_1strx;
	u32 	bSlot_mark_1strx;

//0x10
	u32		connExpectTime;
	u32		conn_start_time;
  	u32		latency_wakeup_tick;


//0x20
	s32		sSlot_mark_conn;	//now master not use
	u32 	sSlot_mark_brx;
	s32		sSlot_mark_conExcept;
	s32		conn_update_pre_sSlotIndex;

	u32 	sSlot_interval;  //u16: 65536*20uS = 1.3S, not enough, max value 4S for BQB, so use u32




//0x30
	u8	rsvd11;
	u8	rsvd22;
	u8	aclTsk_wptr;
	u8	aclTsk_rptr;

//0x38
	//Attention: if not 4B aligned, task scheduler will collapse. SO variable must 4B aligned above !!!
	sch_task_t	aclTsk_fifo[ACL_SLAVE_FIFONUM];


#if (BLS_PROC_MASTER_UPDATE_REQ_IN_IRQ_ENABLE)
	u8		blt_buff_conn[24];
#endif

//0x50
} st_lls_conn_t;

extern	_attribute_aligned_(4)	st_lls_conn_t	blmsSlave[];
extern	st_lls_conn_t	*bls_pconn;
extern	int				bls_conn_sel;




typedef int (*ll_acl_slave_terminate_irq_callback_t)(u16 aclHandle);


bool 	blt_s_connect (rf_packet_connect_t * pInit, bool aux_conn);

int 	blt_brx_start(int conn_idx);
int 	blt_brx_post(void);


void 	blt_brx_timing_init(void);
void 	blt_brx_timing_update(void);


int 	blt_ll_build_acl_slave_schedule(void);

void 	blt_ll_registerAclSlaveTerminateIrqCb(ll_acl_slave_terminate_irq_callback_t  cb);
int	 	blt_ll_set_slave_conn_interval_level (st_ll_conn_t *pc, st_lls_conn_t *ps, u16 conn_interval);

void  	blt_ll_reset_acl_slave(void);

int 	blt_acl_slave_interrupt_task (int flag);
int 	blt_acl_slave_mainloop_task (int flag);

void 	blt_acl_slave_rx_procUpdateReq(u8 *raw_pkt);
void 	blt_acl_slave_tx_procUpdateReq(void);
void 	blt_acl_slave_slotgap_procUpdateReq(void);
int 	blt_ll_conn_chn_phy_update(st_ll_conn_t* pc, u8 *pkt);
/******************************* acl_slave end   ******************************************************************/









/******************************* acl_master start ******************************************************************/

#define			ACL_MASTER_FIFONUM								12
#define			BLM_ENC_PKT_PENDING_NUM  						4
#define			BLM_ENC_PKT_SKIP_ENCRYPT						(BIT(3))



_attribute_aligned_(4)
typedef struct {

	u8		init_pos_idx; 	//initiate timing position index
	u8		updt_pos_idx;
	u16		evtCnt_mark_btx;

	u32		init_pos_msk;  //initiate timing position index
	u32		updt_pos_msk;
	u32     sche_tick_conn;

	u32		slot_idx_1st_btx_mark_update_hold;
	u32		bSlot_mark_position_update_hold;


	u8		rsvd11;
	u8		rsvd22;
	u8		aclTsk_wptr;
	u8		aclTsk_rptr;

	//Attention: if not 4B aligned, task scheduler will collapse. SO variable must 4B aligned above !!!
	sch_task_t	aclTsk_fifo[ACL_MASTER_FIFONUM];

} st_llm_conn_t;

_attribute_aligned_(4)
typedef struct
{
	u8 		wptr;
	u8 		rptr;
	u8		mask;
	u8		num;
	u8 		buff[BLM_ENC_PKT_PENDING_NUM][48];
}blm_pkt_pending_t;

extern	_attribute_aligned_(4)	st_llm_conn_t		blmsMaster[];
extern	_attribute_aligned_(4)  blm_pkt_pending_t 	blmsMasterEncPktPending[];
extern	_attribute_aligned_(4)  st_llm_conn_t      *blm_pconn;


_attribute_aligned_(4)
typedef struct {
	u16		bSlotNum_piece_inter;
	u16		bSlotNum_whole_inter;    //"u8": can not exceed 160 mS


	u16		master_connInter;           //"u8": conn_interval can not exceed 320 mS, "u16" is OK
	u16		u16_rsvd;

	u32		slot_idx_1st_btx_mark;

	u32		position_mask[BLMS_MAX_CONN_MASTER_NUM]; //
	u32		bSlot_mark_position[BLMS_MAX_CONN_MASTER_NUM]; //
} acl_mas_para_t;  //ACL master parameters

extern	_attribute_aligned_(4)	acl_mas_para_t		aclMas_param;

typedef int (*ll_acl_master_terminate_irq_callback_t)(u16 connHandle);
extern ll_acl_master_terminate_irq_callback_t		ll_acl_master_terminate_irq_cb;

bool 	blms_m_connect (rf_packet_connect_t * pInit, u8 *raw_pkt);
int 	blt_btx_start (int conn_idx);
int 	blt_btx_post (void);

void 	blt_ll_registerAclMasterTerminateIrqCb(ll_acl_master_terminate_irq_callback_t  cb);
int 	blt_ll_ctrlAclChClassUpd(unsigned char *pChm);
int		blt_ll_buildAclMasterSchedulerLinklist(void);
void 	blt_ll_calculateAclMasterBslotNumber(void);

ble_sts_t blt_ll_exchangeDataLength (u16 connHandle, u8 opcode, u16 maxTxOct);

/******************************* acl_master end   ******************************************************************/




/******************************* acl_phy start ******************************************************************/

void blt_ll_sendPhyReq(u16 connHandle);
void blt_ll_sendPhyUpdateInd(u16 connHandle);
int  blt_ll_updateConnPhy(u16 connHandle);
int  blt_ll_switchConnPhy(u16 connHandle);
int  blt_cfg_conn_phy_param(ll_conn_phy_t* pconn_phy, le_phy_type_t curPhy, le_coding_ind_t CI);

/**
 * @brief       this function is used to set PHY type for connection, same as API: blc_ll_setPhy
 * @param[in]	connHandle - Connection_Handle Range:0x0000 to 0x0EFF
 * @param[in]	all_phys - preference PHY for TX & RX
 * @param[in]	tx_phys - preference PHY for TX
 * @param[in]	rx_phys - preference PHY for RX
 * @param[in]	phy_options - LE coding indication prefer
 * @return     status, 0x00:  succeed
 * 					   other: failed
 */
ble_sts_t 	blc_hci_le_setPhy(hci_le_setPhyCmd_param_t* para);
void *blt_ll_getAclConnPtr(u16 connHandle);

/******************************* acl_phy end   ******************************************************************/





#endif /* ACL_STACK_H_ */
